
from flask import request
from flask_login import current_user
from flask_restful import Resource, marshal_with, reqparse  # type: ignore
from controllers.errors.character_errors import HTTPCharacterNotExistError
from controllers.errors.emoji_errors import HTTPEmojiPackNotExistError
from controllers.errors.fun_domain_errors import HTTPFunDomainNotExistError, HTTPFunDomainParamError, HTTPFunNotExistError
from controllers.errors.timbre_errors import HTTPTimbreNotExistError
from core.roles.role_check import check_perms
from libs.helper import extract_remote_ip
from libs.login import login_required
from fields.fun_domain_fields_def import fun_domain_fields,fun_domain_list_fields
from werkzeug.exceptions import InternalServerError
from controllers.console import api
from services.errors.character import CharacterNotExistError
from services.errors.emoji import EmojiPackageNotExistError
from services.errors.fun_domain import FunDomainNotExistError, FunDomainParamError, FunNotExistError
from services.errors.timbre import TimbreNotExistError
from services.robot.fun_domain_service import FunDomainService

class RobFunDomainManageApi(Resource):
    @login_required
    @check_perms(perms=['domain:list'])
    @marshal_with(fun_domain_list_fields)
    def get(self):
        argparser = reqparse.RequestParser()
        argparser.add_argument("id",type=str,required=False,location='args')
        argparser.add_argument("name",type=str,required=False,location='args')
        argparser.add_argument("default_character_id",type=str,required=False,location='args')
        argparser.add_argument("default_timbre_id",type=str,required=False,location='args')
        argparser.add_argument("default_emoji_pack_id",type=str,required=False,location='args')
        argparser.add_argument("page",type=int,default=-1,location='args')
        argparser.add_argument("page_size",type=int,default=-1,location='args')
        args = argparser.parse_args()
        return FunDomainService.get_domain_list(current_user.current_tenant_id,args)
    
    @login_required
    @check_perms(perms=['domain:new'])
    @marshal_with(fun_domain_fields)
    def post(self):
        argparser = reqparse.RequestParser()
        argparser.add_argument("name",type=str,required=True,location='json')
        argparser.add_argument("descrip",type=str,required=False,location='json')
        argparser.add_argument("default_character_id",type=str,required=True,location='json')
        argparser.add_argument("default_timbre_id",type=str,required=False,location='json')
        argparser.add_argument("default_emoji_pack_id",type=str,required=False,location='json')
        argparser.add_argument("price",type=float,required=False,location='json')
        argparser.add_argument("funcs",type=str,action="append",required=False,location='json')
        argparser.add_argument("characters",type=str,action="append",required=False,location='json')
        argparser.add_argument("timbres",type=str,action="append",required=False,location='json')
        argparser.add_argument("emoji_packs",type=str,action="append",required=False,location='json')
        args = argparser.parse_args()
        try:
            return FunDomainService.create_domain(current_user,args,extract_remote_ip(request))
        except FunDomainParamError as e:
            raise HTTPFunDomainParamError(e.description)
        except TimbreNotExistError as e:
            raise HTTPTimbreNotExistError(e.timbre_id)
        except CharacterNotExistError as e:
            raise HTTPCharacterNotExistError(e.character_id)
        except EmojiPackageNotExistError as e:
            raise HTTPEmojiPackNotExistError(e.emoji_pack_id)
        except FunNotExistError as e:
            raise HTTPFunNotExistError(e.func_id)
        except Exception as e:
            raise InternalServerError(str(e))
    
    @login_required
    @check_perms(perms=['domain:update'])
    @marshal_with(fun_domain_fields)
    def put(self):
        argparser = reqparse.RequestParser()
        argparser.add_argument("id",type=str,required=True,location='json')
        argparser.add_argument("name",type=str,required=True,location='json')
        argparser.add_argument("descrip",type=str,required=False,location='json')
        argparser.add_argument("default_character_id",type=str,required=False,location='json')
        argparser.add_argument("default_timbre_id",type=str,required=False,location='json')
        argparser.add_argument("default_emoji_pack_id",type=str,required=False,location='json')
        argparser.add_argument("price",type=float,required=False,location='json')
        argparser.add_argument("funcs",type=str,action="append",required=False,location='json')
        argparser.add_argument("characters",type=str,action="append",required=False,location='json')
        argparser.add_argument("timbres",type=str,action="append",required=False,location='json')
        argparser.add_argument("emoji_packs",type=str,action="append",required=False,location='json')
        args = argparser.parse_args()
        try:
            return FunDomainService.update_domain(current_user,args,extract_remote_ip(request))
        except FunDomainNotExistError as e:
            raise HTTPFunDomainNotExistError(e.fun_domain_id)
        except FunDomainParamError as e:
            raise HTTPFunDomainParamError(e.description)
        except TimbreNotExistError as e:
            raise HTTPTimbreNotExistError(e.timbre_id)
        except CharacterNotExistError as e:
            raise HTTPCharacterNotExistError(e.character_id)
        except EmojiPackageNotExistError as e:
            raise HTTPEmojiPackNotExistError(e.emoji_pack_id)
        except FunNotExistError as e:
            raise HTTPFunNotExistError(e.func_id)
        except Exception as e:
            raise InternalServerError(str(e))
        
    @login_required
    @check_perms(perms=['domain:del'])
    def delete(self):
        argparser = reqparse.RequestParser()
        argparser.add_argument("id",type=str,required=True,location='json')
        args = argparser.parse_args()
        fun_domain_id = args.get("id",None)
        try:
            return FunDomainService.del_domain(current_user,fun_domain_id,extract_remote_ip(request))
        except FunDomainNotExistError as e:
            raise HTTPFunDomainNotExistError(e.fun_domain_id)
    

api.add_resource(RobFunDomainManageApi,"/robots/domains")